package cn.iocoder.yudao.module.game.controller.app;

import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.game.controller.admin.gameLog.vo.GameLogSaveReqVO;
import cn.iocoder.yudao.module.game.controller.admin.gameToken.vo.GameTokenSaveReqVO;
import cn.iocoder.yudao.module.game.controller.app.vo.RealPGResult;
import cn.iocoder.yudao.module.game.dal.dataobject.gameToken.GameTokenDO;
import cn.iocoder.yudao.module.game.service.gameLog.GameLogService;
import cn.iocoder.yudao.module.game.service.gameToken.GameTokenService;
import cn.iocoder.yudao.module.game.service.otherGame.JPGService;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
import cn.iocoder.yudao.module.member.service.level.MemberLevelService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import net.sf.json.JSONObject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.enums.UserTypeEnum.MEMBER;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "用户 APP - 用户收件地址")
@RestController
@RequestMapping("/game/jpg")
@Validated
public class AppJPGController {

    @Resource
    private JPGService jpgService;
    @Resource
    private GameLogService gameLogService;

    @Resource
    private MemberUserService memberUserService;
    @Resource
    private PayWalletService payWalletService;
    @Resource
    private PayWalletTransactionService payWalletTransactionService;
    @Resource
    private MemberLevelService memberlevelService;
    @Resource
    private GameTokenService gameTokenService;

    @PostMapping("/login")
    @Operation(summary = "创建用户收件地址")
    public CommonResult<Map<String, Object>> login(@RequestBody Map<String, Object> params) throws Exception {
        JSONObject res = jpgService.login(params);

        JSONObject data = (JSONObject) res.get("data");

        GameTokenSaveReqVO createReqVO = new GameTokenSaveReqVO();
        createReqVO.setMemberId(Long.valueOf(data.get("user_id").toString()));
        createReqVO.setToken(data.get("token").toString());
        createReqVO.setGameType("JPG");
        gameTokenService.createToken(createReqVO);

        MemberUserUpdateReqVO memberUserUpdateReqVO = new MemberUserUpdateReqVO();
        memberUserUpdateReqVO.setNickname(data.get("user_id").toString());
        memberUserUpdateReqVO.setId(Long.valueOf(data.get("player_id").toString()));
        memberUserService.updateUser(memberUserUpdateReqVO);

        return success(res);
    }

    @PostMapping("/getGame")
    @Operation(summary = "创建用户收件地址")
    public CommonResult<Map<String, Object>> getGame(@RequestBody Map<String, Object> params) throws Exception {
        GameTokenDO gameTokenDO = gameTokenService.getToken(new LambdaQueryWrapper<GameTokenDO>()
                .eq(GameTokenDO::getToken, params.get("userToken").toString())
                .eq(GameTokenDO::getGameType, "JPG"));
        params.put("user_token", gameTokenDO.getToken());

        return success(jpgService.getGame(params));
    }

    @PostMapping("/getBalance")
    @Operation(summary = "创建用户收件地址")
    public CommonResult<Map<String, Object>> getBalance(@RequestBody Map<String, Object> params) throws Exception {
        Map<String, Object> res = new HashMap<>();
        res.put("currency_code", "BRL");
        res.put("updated_time", System.currentTimeMillis());
        PayWalletDO payWalletDO = payWalletService.getOrCreateWallet(Long.valueOf(params.get("UseID").toString()), MEMBER.getValue());
        res.put("balance_amount", new BigDecimal(payWalletDO.getBalance()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
        return success(res);
    }

    @PostMapping("/setBalance")
    @Operation(summary = "创建用户收件地址")
    public CommonResult<Map<String, Object>> setBalance(@RequestBody Map<String, Object> params) throws Exception {
        Map<String, Object> bonus = new HashMap<>();
        bonus.put("5", 50);
        bonus.put("10", 50);
        bonus.put("15", 50);
        bonus.put("20", 50);
        bonus.put("25", 50);
        bonus.put("30", 50);
        bonus.put("40", 100);
        bonus.put("50", 100);
        bonus.put("60", 100);
        bonus.put("70", 100);
        bonus.put("80", 100);
        bonus.put("90", 100);
        bonus.put("100", 100);
        bonus.put("150", 500);
        bonus.put("200", 500);
        bonus.put("250", 500);
        bonus.put("300", 500);
        bonus.put("350", 500);
        bonus.put("400", 500);
        bonus.put("450", 500);
        bonus.put("500", 500);
        bonus.put("600", 1000);
        bonus.put("700", 1000);
        bonus.put("800", 1000);
        bonus.put("900", 1000);
        bonus.put("1000", 1000);
        bonus.put("1500", 5000);
        bonus.put("2000", 5000);
        bonus.put("2500", 5000);
        bonus.put("3000", 5000);
        bonus.put("4000", 10000);
        bonus.put("5000", 10000);
        bonus.put("6000", 10000);
        bonus.put("7000", 10000);
        bonus.put("8000", 10000);
        bonus.put("9000", 10000);
        bonus.put("10000", 10000);

        PayWalletDO payWalletDO = payWalletService.getOrCreateWallet(Long.valueOf(params.get("UseID").toString()), MEMBER.getValue());

        createLog(Long.valueOf(params.get("UseID").toString()), params);

        payWalletService.reduceWalletBalance(payWalletDO.getId(),
                params.get("Term").toString(),
                PayWalletBizTypeEnum.BET,
                (long) (Double.parseDouble(params.get("Bet").toString()) * 100));
        payWalletService.addWalletBalance(payWalletDO.getId(),
                params.get("Term").toString(),
                PayWalletBizTypeEnum.WIN,
                (long) (Double.parseDouble(params.get("Award").toString()) * 100));

        payWalletDO = payWalletService.getOrCreateWallet(Long.valueOf(params.get("UseID").toString()), MEMBER.getValue());

        MemberUserDO memberUserDO = memberUserService.getUser(Long.valueOf(params.get("UseID").toString()));

        memberlevelService.addExperience(memberUserDO.getId(),
                (long) (Double.parseDouble(params.get("Bet").toString())),
                MemberExperienceBizTypeEnum.ORDER_GIVE,
                params.get("Term").toString());

        List<PayWalletTransactionDO> payWalletTransactionDOS = payWalletTransactionService.list(memberUserDO.getCode(), PayWalletBizTypeEnum.RECHARGE.getType());
        String sumP = payWalletTransactionService.betSum(memberUserDO.getCode(), PayWalletBizTypeEnum.BET.getType(), 0).get("sum_p").toString();

        MemberUserDO fReferrerUser = memberUserService.getUserByReferrer(memberUserDO.getReferrer());
        if (fReferrerUser != null) {
            if (payWalletTransactionDOS.size() > 0 && (payWalletTransactionDOS.get(0).getPrice() / 100) >= 20 && Long.valueOf(sumP) >= 50 && memberUserDO.getReferrerStatus().equals(0)) {
                if (bonus.get(String.valueOf(fReferrerUser.getQualifiedNum() + 1)) != null) {
                    payWalletService.addWalletBalance(payWalletDO.getId(),
                            params.get("Term").toString(),
                            PayWalletBizTypeEnum.GENERALIZATION_COMMISSION,
                            (long) (Double.parseDouble(bonus.get(String.valueOf(fReferrerUser.getQualifiedNum() + 1)).toString()) * 100));
                }

                MemberUserUpdateReqVO memberUserUpdateReqVO = new MemberUserUpdateReqVO();
                memberUserUpdateReqVO.setReferrerStatus(1);
                memberUserUpdateReqVO.setQualifiedNum(fReferrerUser.getQualifiedNum() + 1);
                memberUserUpdateReqVO.setId(fReferrerUser.getId());
                memberUserService.updateUser(memberUserUpdateReqVO);
            }

            PayWalletDO fReferrerPayWalletDO = payWalletService.getOrCreateWallet(fReferrerUser.getId(), UserTypeEnum.MEMBER.getValue());
            payWalletService.addWalletBalance(fReferrerPayWalletDO.getId(),
                    params.get("Term").toString(),
                    PayWalletBizTypeEnum.BET_COMMISSION,
                    (long) (Double.parseDouble(params.get("Bet").toString()) * 100 * 0.03 / 100));

            MemberUserDO sReferrerUser = memberUserService.getUserByReferrer(fReferrerUser.getReferrer());
            if (sReferrerUser != null) {
                PayWalletDO sReferrerPayWalletDO = payWalletService.getOrCreateWallet(sReferrerUser.getId(), UserTypeEnum.MEMBER.getValue());
                payWalletService.addWalletBalance(sReferrerPayWalletDO.getId(),
                        params.get("Term").toString(),
                        PayWalletBizTypeEnum.BET_COMMISSION,
                        (long) (Double.parseDouble(params.get("Bet").toString()) * 100 * 0.01 / 100));

            }
        }

        Map<String, Object> res = new HashMap<>();
        res.put("currency_code", "BRL");
        res.put("updated_time", System.currentTimeMillis());
        res.put("balance_amount", new BigDecimal(payWalletDO.getBalance()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
        return success(res);
    }

    private void createLog(Long memberId, Map<String, Object> params) {

        String result = params.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining(", "));

        GameLogSaveReqVO createReqVO = new GameLogSaveReqVO();
        createReqVO.setMemberId(memberId);
        createReqVO.setGameId(Long.valueOf(params.get("GameID").toString()));
        createReqVO.setPreChangeCoin(new BigDecimal(params.get("Bet").toString()));
        createReqVO.setOpeCoin(new BigDecimal(params.get("UpdateCredit").toString()));
        createReqVO.setRemark(result);
        gameLogService.createLog(createReqVO);
    }

}
